package com.ksyun.campus.client;

import com.ksyun.campus.client.common.context.ServerContext;
import com.ksyun.campus.client.util.MD5Util;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static org.junit.Assert.assertEquals;


public class testWriteAndRead {
    private EFileSystem eFileSystem = new EFileSystem("fbsFileSystem");
    public String originalMD5;
    /**
     * 在每次测试前启动Zookeeper 将获取的集群信息存入ThreadLocal
     * @throws Exception
     */
    @Before
    public void createZooConnect() throws Exception {
        eFileSystem.clientToMetaService.zkUtil.postCons();
        System.out.println("测试从ThreadLocal中获取metaServerList: "+ServerContext.getMetaServerList());
    }


    @Test
    public void testWrite() {
        FSOutputStream fsOutputStream = eFileSystem.create("/data/first/hi.txt");
        System.out.println("查看当前FSOutputStream的信息" + fsOutputStream);

        //替换成测试用的文件，
        String file = "E:\\Occupation\\minfs-project\\minfs\\hi.txt";
        Path filePath = Paths.get(file);
        try {
            byte[] fileContent = Files.readAllBytes(filePath);
            System.out.println("文件原始byte: "+fileContent);
            String contentAsString = new String(fileContent, StandardCharsets.UTF_8);
            System.out.println("文件原始字符串: "+contentAsString);

            //1. 一次写入一个字节
//            for(byte i : fileContent){
//                fsOutputStream.write(i);
//            }

            //2. 写入操作(一次写入整个文件)
            fsOutputStream.write(fileContent);


            //3. 一次写入3个字节
//            for (int i=0 ;i<fileContent.length;i=i+3){
//                fsOutputStream.write(fileContent,i,3);
//            }

            // 计算原始文件的 MD5
            originalMD5 = MD5Util.calculateMD5(fileContent);
            System.out.println("原始文件的MD5: " + originalMD5);

            //close文件输出流向dataServer发送写请求
            fsOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testRead() {
        FSInputStream fsInputStream = eFileSystem.open("/data/first/hi.txt");
        System.out.println("文件输入流的信息：" + fsInputStream);
        //获取打开文件的大小
        int size = (int)fsInputStream.getStatInfo().getSize();
        try {

            //1. 每次读单个字节
//            while (size-->0){
//                int read = fsInputStream.read();
//                System.out.println("读出的单个字节: "+(char)read);
//            }

            //2. 每次读2个字节数组
//            byte[] fileContent = new byte[2];
//            int count = 7;
//            while (count-- > 0) {
//                int read = fsInputStream.read(fileContent);
//                System.out.println("从文件系统读到的byte[]数组的大小为: "+read);
//                System.out.println("byte[]数组内容为 : " + fileContent);
//                String contentAsString = new String(fileContent, StandardCharsets.UTF_8);
//                System.out.println("将数组转为UTF_8格式: " + contentAsString);
//            }

            //3. 每次读整个文件
            byte[] fileTotalBytes =new byte[size];
            int read = fsInputStream.read(fileTotalBytes,0,size);
            System.out.println("从文件系统读到的byte[]数组的大小为: "+read);
            System.out.println("byte[]数组内容为 : " + fileTotalBytes);
            String contentAsString = new String(fileTotalBytes, StandardCharsets.UTF_8);
            System.out.println("将数组转为UTF_8格式: " + contentAsString);


            if (read != size) {
                throw new IOException("读取的文件大小不一致");
            }
            // 计算读取文件的 MD5
            String readMD5 = MD5Util.calculateMD5(fileTotalBytes);
            System.out.println("读取文件的MD5: " + readMD5);
            System.out.println("原始MD5: "+originalMD5);

            if(readMD5.equals(originalMD5)){
                System.out.println("写入和读出的文件MD5一致");
            }else {
                System.out.println("写入和读出的文件MD5不一致");
            }

            // 比较 MD5
            assertEquals("写入和读出的文件MD5不一致", originalMD5, readMD5);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 关闭zookeeper连接
     */
    @After
    public void closeZK(){
        eFileSystem.clientToMetaService.zkUtil.close();
    }

    //      模拟创建MetaServer节点
//        MetaServer metaServer=new MetaServer(true,"129.0.0.1",8001);
//        MetaServer metaServer2 =new MetaServer(false,"123.0.0.1",8100);
//        String jsonString = JSON.toJSONString(metaServer);
//        String jsonString2 = JSON.toJSONString(metaServer2);
//        client.create().forPath(zkMetaServerPath+"/server1",jsonString.getBytes());
//        client.create().forPath(zkMetaServerPath+"/server2",jsonString2.getBytes());


//      模拟创建dataServer节点
//        DataServer dataServer1=new DataServer("rack","zone","111.11.11.1",9000,20,100,2);
//        DataServer dataServer2=new DataServer("rack","zone","111.11.11.2",9001,20,100,2);
//        DataServer dataServer3=new DataServer("rack","zone","111.11.11.3",9002,20,100,2);
//        DataServer dataServer4=new DataServer("rack","zone","111.11.11.4",9003,20,100,2);
//
//        String jsonString1 = JSON.toJSONString(dataServer1);
//        String jsonString2 = JSON.toJSONString(dataServer2);
//        String jsonString3 = JSON.toJSONString(dataServer3);
//        String jsonString4 = JSON.toJSONString(dataServer4);
//
//        client.create().forPath(ServerConfiguration.ZKDATASERVERPATH +"/server1",jsonString1.getBytes());
//        client.create().forPath(ServerConfiguration.ZKDATASERVERPATH +"/server2",jsonString2.getBytes());
//        client.create().forPath(ServerConfiguration.ZKDATASERVERPATH +"/server3",jsonString3.getBytes());
//        client.create().forPath(ServerConfiguration.ZKDATASERVERPATH +"/server4",jsonString4.getBytes());


//        //连接zookeeper时,获取到主从MetaServer的信息
//        List<String> serverStringList = client.getChildren().forPath(zkMetaServerPath);
//        List<MetaServer> metaServerList=serverStringList.stream().map(each->{
//            try {
//                String childrenPath=zkMetaServerPath+"/"+each;
//                byte[] MetaServerBytes = client.getData().forPath(childrenPath);
//                System.out.println("从zookeeper中获取MetaServer的信息:"+new String(MetaServerBytes));
//                return JSON.parseObject(MetaServerBytes, MetaServer.class);
//            } catch (Exception e) {
//                throw new RuntimeException(e);
//            }
//        }).collect(Collectors.toList());
//        System.out.println("metaServer列表: "+metaServerList);
//        ServerContext.updateMetaServerList(metaServerList);
//        System.out.println("-----------------------------");
//        System.out.println(ServerContext.getMetaServerList());
}
